package cn.msy.asm;

import cn.msy.constant.Path;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import java.io.*;

/**
 * @author Irving
 * @create 2021/6/30
 * @desc 定义一个类,生成class文件
 **/
public class ClassWriter_ {

    public static void classWriter() throws IOException {
        ClassWriter cw = new ClassWriter(0);
        // 这里定义了接口
        // V1_7指的是JDK版本
        // ACC_XXX指的是类的修饰符
        // pkg/Comparable表示类的名字 pkg.Comparable
        // 参数4表示的是类参数,泛型
        // java/lang/Object 该类继承的超类,也就是父类,接口类默认继承至Object
        // new String[] { "pkg/Mesurable"}
        cw.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT + Opcodes.ACC_INTERFACE,
                "pkg/Comparable", null, "java/lang/Object", new String[]{"pkg/Mesurable"});

        // 这里定义了一个常量
        // LESS表示为该常量的常量名
        // I表示该常量的类型 I代表int
        // null部分表示的是泛型
        // new Integer(-1)定义该常量的值,也就是给这个常量赋值
        cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "LESS", "I",
                null, new Integer(-1)).visitEnd();
        cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "EQUAL", "I",
                null, new Integer(0)).visitEnd();
        cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "GREATER", "I",
                null, new Integer(1)).visitEnd();

        // 定义接口中的方法
        // compareTo定义方法名
        // (Ljava/lang/Object;)I 对该方法进行描述,左侧括号内表示方法参数,右侧代表方法的返回值
        // 参数4表示该类使用的泛型
        // 参数5指明该方法会抛出的异常
        cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "compareTo",
                "(Ljava/lang/Object;)I", null, null).visitEnd();
        cw.visitEnd();
        byte[] b = cw.toByteArray();
        File file = new File(Path.PATH_DESKTOP + "Comparable.class");
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        fileOutputStream.write(b);
        fileOutputStream.close();
    }

}
